import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;


//CNG => Create New group
//JIG => Join Into Group
//MQ  => Master Quits

public class ClientHandler extends Thread {
	
	private InetAddress clientIP = null;
	private RtpPacket rtpPacket;
	private DatagramPacket datagramPacket;
	private int clientPort;
	private boolean isRunning = true;
	private ArrayList<String> groups;
	private Semaphore mutex;
	private GroupDataInterface groupData;
	private DatagramSocket socket;
	
	public ClientHandler(DatagramPacket datagramPacket, Semaphore mutex, GroupDataInterface groupData, DatagramSocket socket) {		
		
		this.datagramPacket = datagramPacket;
		this.groupData = groupData;
		this.mutex = mutex;		
		this.socket = socket;
		
	}
	
	 public void run() {
		 
		this.rtpPacket = new RtpPacket(datagramPacket.getData(), datagramPacket.getData().length);	
		this.clientIP = datagramPacket.getAddress();
		this.clientPort = datagramPacket.getPort();
		
		if(this.rtpPacket.getP() == 1 && this.rtpPacket.getX() == 1) {
			
			String data = new String(this.rtpPacket.getPayload());
			String[] groupInformation = data.split(",");
			
			RtpPacket responsePacket = new RtpPacket();
			DatagramPacket datagramPacket = new DatagramPacket(new byte[1], 1, this.clientIP, this.clientPort);
			
			
			System.out.println("CLIENT "+groupInformation[0]);
			
			/*
			 * Create New Group
			 * */
			if(groupInformation[0].equals("CNG")) {			
			
				String ok = "OK,";
				String fail = "FAIL,";
				
				byte[] okBytes = ok.getBytes();
				byte[] failBytes = fail.getBytes();
				
				byte[] buffer = new byte[524];	
				
				try {
					this.mutex.acquire();
					
					if(this.groupData.existGroup(groupInformation[1])) {
						responsePacket.setPayload(failBytes, failBytes.length);
						datagramPacket.setData(responsePacket.getRtpPacketinByte());	
						this.socket.send(datagramPacket);
						System.out.println("Existiert");						
					}
					
					else {
						responsePacket.setPayload(okBytes, okBytes.length);
						datagramPacket.setData(responsePacket.getRtpPacketinByte());
						this.socket.send(datagramPacket);
						this.groupData.createNewGroup(groupInformation[1], groupInformation[2], this.clientIP, this.clientPort);						
						System.out.println("Existiert nicht");
					}
					
					this.mutex.release();
					
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			
			
			else if(groupInformation[0].equals("GUFG")) {
				
				ArrayList<String> memberList = this.groupData.getMemberNamesByGivenGroup(groupInformation[1]);
				
				String memberString = "";
				
				for(int i = 0; i < memberList.size(); i++ ) {
					
					memberString = memberList.get(i)+","+memberString;					
				}				
				
				System.out.println(memberString);
				
				
				byte[] membersByte = memberString.getBytes();
				responsePacket.setPayload(membersByte, membersByte.length);
				datagramPacket.setData(responsePacket.getRtpPacketinByte());	
				try {
					this.socket.send(datagramPacket);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				
			}
			
			else if(groupInformation[0].equals("JG")) {
				
				ArrayList<String> groupList = this.groupData.getAllGroups();
				String groupString;
				
				if(groupList.size() == 0) {				
					groupString = "EMPTY,";
				}
				
				else {
					groupString = ",";
					for(int i = 0; i < groupList.size(); i++ ) {
						
						groupString = groupList.get(i)+","+groupString;					
					}
					
				}
				
				byte[] groupByte = groupString.getBytes();
				responsePacket.setPayload(groupByte, groupByte.length);
				datagramPacket.setData(responsePacket.getRtpPacketinByte());	
				try {
					this.socket.send(datagramPacket);
				} catch (IOException e) {
						// TODO Auto-generated catch block
					e.printStackTrace();
				}
					
				
				
			}
				
		}
			 
				 		 		 
    }
	
	 
	String convertByteToString(byte[] data) {
		
		return (new String(data));
	}
	
	public void send(byte[] packet, InetAddress remoteAdress, int remotePort) {	 		 
		 
		 DatagramPacket datagramPacket = new DatagramPacket(new byte[1], 1, remoteAdress, remotePort);
		 datagramPacket.setData(packet);
	 }	
		
	 
	
}
